///---------------功能说明-----------------///
///1.创建方块到画面
///2.控制方块移动
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace TetrisGame {
    public class TetriControler : MonoBehaviour
    {
        public int Wide;
        public int High;
        public float Size;
        TetrisMoveArray tetrisMoveArray;
        TetrisStaticArray tetrisStaticArray;
        Tetri[] tetriMoveArray;
        Tetri[] tetriStaticArray;
        TetrisObjectPool tetrisPool;
        bool GameStart;
        public float MoveSpeed;
        VectorToInt moveArrayVec;
        int[,] moveArray;
        public TetrisObjectPool TetrisPool {
            get 
            {
                if (!tetrisPool)
                {
                    tetrisPool = TetrisObjectPool.Instance;
                }
                return tetrisPool;
            }
        }

        // Start is called before the first frame update
        void Start()
        {
            tetrisMoveArray = new TetrisMoveArray();
            tetrisStaticArray = new TetrisStaticArray(Wide, High);
            tetriStaticArray = new Tetri[Wide * High];
            tetriMoveArray = new Tetri[6];
            GameStart = true;
            moveArrayVec = new VectorToInt(Wide, High);
            GamePlay();
      
        }
         void Update()
        {
            if (Input.GetKeyDown(KeyCode.D))
            {
                if (!tetrisStaticArray.HorizontalOverlap(moveArray, moveArrayVec))
                {
                    moveArrayVec.MoveValueX(-1);
                    Debug.Log(moveArrayVec.x);
                }
            }
            if (Input.GetKeyDown(KeyCode.A))
            {
                if (!tetrisStaticArray.HorizontalOverlap(moveArray, moveArrayVec))
                {
                    moveArrayVec.MoveValueX(1);
                    Debug.Log(moveArrayVec.x);
                }
            }
            if (Input.GetKeyDown(KeyCode.Space))
            {
                Debug.Log("a");
            
                for (int i = 0; i < tetriMoveArray.Length; i++)
                {
                    if (tetriMoveArray[i])
                    {
                        TetrisPool.Recycle(tetriMoveArray[i]);
                        tetriMoveArray[i] = null;
                    }
                }
                RotateArray(ref moveArray);
            }
        }

        void GamePlay()
        {
            TetriDown();
            void TetriDown()
            {
                if (GameStart)
                {
                    int randomWide = UnityEngine.Random.Range(0, Wide - 1);
                    int randomType = UnityEngine.Random.Range(0, 7);
                    moveArray = tetrisMoveArray.GetTypeArray((TetrisTypeEnum)randomType);
                    IEnumerator coroutine = TetriMove( randomWide, TetriDown);
                    StartCoroutine(coroutine);
                }
                CreatStaticTetril();
            }

        }
        void GameOver()
        {
            GameStart = false;
        }
        /// <summary>
        /// 控制垂直方块移动，并判断是否停止
        /// </summary>
        /// <param name="tetrisType"></param>
        /// <param name="random"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        IEnumerator TetriMove( int random, Action action = null)
        {
            int y = High;
            moveArrayVec.SetValue(random, y);
            while (y > 0)
            {
            
                if (tetrisStaticArray.DwonOverlap(moveArray, moveArrayVec) || y == 1)
                {
                  //  int[,] array = tetrisMoveArray.GetTypeArray(tetrisType);
                    if (moveArray.GetLength(1)+ moveArrayVec.y>High)
                    {
                        GameOver();
                    }
                    else
                    {
                        tetrisStaticArray.AddArray(moveArray, moveArrayVec);
                    }
                 
                    y = 0;
                  //  moveArray.Initialized();
                    yield return new WaitForSeconds(MoveSpeed);
                }
                else
                {
                    yield return new WaitForSeconds(MoveSpeed);
                    moveArrayVec.SetValueY(y--);
                    CreatMoveTetril(moveArray);
                }
            }
            if (action != null)
            {
                action();
            }
        }
        void CreatMoveTetril(int[,] array)
        {
            
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    int count = i * array.GetLength(1) + j;
                    //if (tetriMoveArray[count])
                    //{
                    //    TetrisPool.Recycle(tetriMoveArray[count]);
                    //}

                    if (array[i, j] == 1)
                    {
                        if (!tetriMoveArray[count])
                        {
                            Tetri tetri = TetrisPool.Allocate();
                            tetri.Postion(new Vector3((i + moveArrayVec.x) * Size, j + (moveArrayVec.y) * Size, transform.position.z));
                            tetriMoveArray[count] = tetri;
                        }
                        else if (tetriMoveArray[count])
                        {
                            Tetri tetri = tetriMoveArray[count];
                            tetri.Postion(new Vector3((i + moveArrayVec.x) * Size, j + (moveArrayVec.y) * Size, transform.position.z));
                        }
                    }
                }
            }
        }
        void CreatStaticTetril()
        {
            int[,] array = tetrisStaticArray.TetrisArray;
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    int count = i * array.GetLength(1) + j;
                    if (array[i, j] == 1 && !tetriStaticArray[count])
                    {
                        Tetri tetri = TetrisPool.Allocate();
                        tetri.Postion(new Vector3(i * Size, j * Size, transform.position.z));
                        tetriStaticArray[count] = tetri;
                    }
                }
            }
        }
      

        void RotateArray(ref int[,]array)
        {
            int wide = array.GetLength(0);
            int high = array.GetLength(1);
            int[,] rotateArray = new int[high, wide];
            for (int i = 0; i < wide; i++)
            {
                for (int j = 0; j < high; j++)
                {
                    rotateArray[j, i] = array[i, high - 1 - j];
                }
            }
            array = rotateArray;

        }

    } 
}
